package com.maxus.mini.ecard.open.api.controller.file;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.swing.ImageIcon;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.dubbo.config.annotation.Reference;
import com.maxus.mini.common.Constants;
import com.maxus.mini.common.utils.BeanUtilsExtended;
import com.maxus.mini.common.utils.ColorUtil;
import com.maxus.mini.common.utils.StringUtil;
import com.maxus.mini.common.vo.ResBody;
import com.maxus.mini.ecard.data.api.ecard.ECardService;
import com.maxus.mini.ecard.data.api.user.UserService;
import com.maxus.mini.ecard.entity.ecard.ECard;
import com.maxus.mini.ecard.entity.user.User;
import com.maxus.mini.ecard.open.api.controller.BaseController;
import com.maxus.mini.ecard.open.api.vo.req.P100100Vo;
import com.maxus.mini.ecard.open.api.vo.res.PR100099Vo;
import com.maxus.mini.ecard.open.api.vo.res.PR100100Vo;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 文件controller
 * 
 * @author wujinsong
 *
 */
@RestController()
@RequestMapping(value = "api/v1.0/file")
public class FileController extends BaseController {
	@Reference(version = "1.0.0")
	private UserService<User, User> userService;
	@Reference(version = "1.0.0")
	private ECardService eCardService;

	/**
	 * 上传附件
	 * 
	 * @param req
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	@RequestMapping(value = "upload")
	@ResponseBody()
	public ResBody upload(MultipartFile file, HttpServletRequest request) {
		PR100099Vo retVo = new PR100099Vo();

		HashMap umap = this.uploadFile(file, Constants.ROOT_RES_DIR);
		retVo.setPath(umap.get("path").toString());

		return retVo;
	}

	/**
	 * 上传附件
	 * 
	 * @param file
	 * @param path
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private HashMap uploadFile(MultipartFile file, String path) {
		InputStream in = null;
		OutputStream out = null;
		FileInputStream inStream = null;
		FileOutputStream outStream = null;
		String filePath = null;
		HashMap map = new HashMap();
		try {
			String uid = UUID.randomUUID().toString();
			uid = uid.toString().replace("-", "");
			StringBuilder stringBuilder = new StringBuilder();
			String name = file.getName();
			String suffix = "png";
			if (name.endsWith(".jpg"))
				suffix = "jpg";
			String dirName = Constants.df.format(System.currentTimeMillis());
			stringBuilder.append(path).append(Constants.RES_DIR).append("/").append(dirName);
			File dir = new File(stringBuilder.toString());
			if (!dir.exists())
				dir.mkdirs();
			stringBuilder.append("/").append(uid).append(".").append(suffix);
			File saveDir = new File(stringBuilder.toString());
			filePath = Constants.RES_DIR + "/" + dirName + "/" + uid + "." + suffix;
			in = file.getInputStream();
			out = new FileOutputStream(saveDir);
			byte[] buffer = new byte[5120];
			int len = 0;

			while ((len = in.read(buffer)) != -1) {
				out.write(buffer, 0, len);
			}
			out.flush();

			in.close();

			in = file.getInputStream();
			BufferedImage inputBufImage = ImageIO.read(in);
			int width = inputBufImage.getWidth();
			int height = inputBufImage.getHeight();

			map.put("width", width);
			map.put("height", height);
			map.put("path", filePath);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
				if (in != null)
					in.close();
				if (inStream != null)
					inStream.close();
				if (outStream != null)
					outStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return map;
	}

	/**
	 * 
	 * @param req
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "drawImage")
	@ResponseBody()
	public ResBody drawImage(@RequestBody P100100Vo req, HttpServletRequest request) throws Exception {
		PR100100Vo retVo = new PR100100Vo();

		Color markContentColor = ColorUtil.parseToColor(req.getColor().substring(1));
		String uid = UUID.randomUUID().toString();
		uid = uid.toString().replace("-", "");
		String suffix = "png";
		String dirName = Constants.df.format(System.currentTimeMillis());
		String filePath = Constants.RES_DIR + "/" + dirName + "/" + uid + "." + suffix;
		String resourcesPath = FileController.class.getClassLoader().getResource("").getPath() + "static";

		FileController.createStringMark(resourcesPath + req.getPath(), req.getContent(), markContentColor, 100,
				Constants.ROOT_RES_DIR + filePath);
		retVo.setPath(filePath);
		
		User user = userService.find(req.getUserId());
		ECard eCard = new ECard();
		BeanUtilsExtended.copyProperties(eCard, req);
		eCard.setTemplate(false);
		eCard.setUser(user);
		eCard.setPicUrl(filePath);
		
		ECard parent = eCardService.find(req.getTemplateId());
		eCard.setParent(parent);
		eCardService.save(eCard);

		return retVo;
	}

	// 给jpg添加文字
	public static boolean createStringMark(String filePath, String markContent, Color markContentColor, float qualNum,
			String outPath) throws Exception {
		String uid = UUID.randomUUID().toString();
		uid = uid.toString().replace("-", "");
		File tempDir = new File(Constants.ROOT_RES_DIR + Constants.RES_TEMP);
		if (!tempDir.exists())
			tempDir.mkdirs();

		// String dest = Constants.ROOT_RES_DIR + Constants.RES_TEMP + uid +
		// ".png";
		// File sourceFile = new File(filePath);
		// File destFile = new File(dest);
		// FileController.zoomImage(sourceFile, destFile, width, 0);
		// FileController.zipImageFile(filePath, width, height,1f,"33");
		ImageIcon imgIcon = new ImageIcon(filePath);
		Image theImg = imgIcon.getImage();
		int width = theImg.getWidth(null) == -1 ? 200 : theImg.getWidth(null);
		int height = theImg.getHeight(null) == -1 ? 200 : theImg.getHeight(null);
		BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics2D g = bimage.createGraphics();
		g.setColor(markContentColor);
		g.setBackground(Color.red);
		g.drawImage(theImg, 0, 0, null);
		g.setFont(new Font(null, Font.PLAIN, 14)); // 字体、字型、字号
		int y = 0;
		List<String> list = StringUtil.stringSpilt(markContent, 8);

		for (String string : list) {
			g.drawString(new String(string), (int) ((width / 2) * 1.2), 120 + y); // 画文字
			y += 24;
		}

		g.dispose();
		try {
			File dir = new File(outPath.substring(0, outPath.lastIndexOf("/")));
			if (!dir.exists())
				dir.mkdirs();
			FileOutputStream out = new FileOutputStream(outPath); // 先用一个特定的输出文件名
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
			param.setQuality(qualNum, true);
			encoder.encode(bimage, param);
			out.close();
		} catch (Exception e) {
			return false;
		}

		return true;
	}

	/**
	 * 
	 * @param src
	 * @param dest
	 * @param w
	 * @param h
	 * @throws Exception
	 */
	public static void zoomImage(File originalFile, File resizedFile, int newWidth, float quality) throws Exception {
		if (quality > 1) {
			throw new IllegalArgumentException("Quality has to be between 0 and 1");
		}

		ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
		Image i = ii.getImage();
		Image resizedImage = null;

		int iWidth = i.getWidth(null);
		int iHeight = i.getHeight(null);

		if (iWidth > iHeight) {
			resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
		} else {
			resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
		}

		// This code ensures that all the pixels in the image are loaded.
		Image temp = new ImageIcon(resizedImage).getImage();

		// Create the buffered image.
		BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
				BufferedImage.TYPE_INT_RGB);

		// Copy image to buffered image.
		Graphics g = bufferedImage.createGraphics();

		// Clear background and paint the image.
		g.setColor(Color.white);
		g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
		g.drawImage(temp, 0, 0, null);
		g.dispose();

		// Soften.
		float softenFactor = 0.05f;
		float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor,
				0 };
		Kernel kernel = new Kernel(3, 3, softenArray);
		ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
		bufferedImage = cOp.filter(bufferedImage, null);

		// Write the jpeg to a file.
		FileOutputStream out = new FileOutputStream(resizedFile);

		// Encodes image as a JPEG data stream
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);

		param.setQuality(quality, true);

		encoder.setJPEGEncodeParam(param);
		encoder.encode(bufferedImage);
	}

	public static String zipImageFile(String oldFile, int width, int height, float quality, String smallIcon) {
		if (oldFile == null) {
			return null;
		}
		String newImage = null;
		try {
			/** 对服务器上的临时文件进行处理 */
			Image srcFile = ImageIO.read(new File(oldFile));
			/** 宽,高设定 */
			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			tag.getGraphics().drawImage(srcFile, 0, 0, width, height, null);
			String filePrex = oldFile.substring(0, oldFile.indexOf('.'));
			/** 压缩后的文件名 */
			newImage = filePrex + smallIcon + oldFile.substring(filePrex.length());
			/** 压缩之后临时存放位置 */
			FileOutputStream out = new FileOutputStream(newImage);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
			/** 压缩质量 */
			jep.setQuality(quality, true);
			encoder.encode(tag, jep);
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return newImage;
	}

}
